#tag Class
Class CFSet
Inherits CFType
Implements CFPropertyList
	#tag Event
		Function ClassID() As UInt32
		  return me.ClassID
		End Function
	#tag EndEvent

	#tag Event
		Function VariantValue() As Variant
		  // convert to a REALbasic Collection. Not very efficient but the only suitable in RB
		  
		  dim outCollection as new Collection
		  
		  for each setValue as CFType in me.Values
		    outCollection.add setValue
		  next
		  
		  return outCollection
		  
		End Function
	#tag EndEvent


	#tag Method, Flags = &h0
		 Shared Function ClassID() As UInt32
		  #if targetMacOS
		    declare function TypeID lib CarbonLib alias "CFSetGetTypeID" () as UInt32
		    static id as UInt32 = TypeID
		    return id
		  #endif
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Constructor(theSet as CFSet)
		  // The Copy Constructor
		  
		  #if TargetMacOS
		    declare function CFSetCreateCopy lib CarbonLib (allocator as Ptr, theSet as Ptr) as Ptr
		    
		    if not (theSet is nil) then
		      super.Constructor CFSetCreateCopy(nil, theSet.Reference), true
		    end if
		  #endif
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Sub Constructor(theValues() as CFType)
		  
		  #if targetMacOS
		    dim callBacks as Ptr = Carbon.Bundle.DataPointerNotRetained("kCFTypeSetCallBacks")
		    
		    declare function CFSetCreate lib CarbonLib (allocator as Ptr, values as Ptr, numValues as Integer, callBacks as Ptr) as Ptr
		    
		    if UBound(theValues) >= 0 then
		      dim valueBlock as new MemoryBlock(4*(1 + UBound(theValues)))
		      dim offset as Integer = 0
		      for i as Integer = 0 to UBound(theValues)
		        valueBlock.Ptr(offset) = theValues(i).Reference
		        offset = offset + 4
		      next
		      // create with presets
		      super.Constructor CFSetCreate(nil, valueBlock, 1 + UBound(theValues), callbacks), true
		    else
		      // create empty set
		      super.Constructor CFSetCreate(nil, nil, 0, callbacks), true
		    end if
		  #endif
		  
		End Sub
	#tag EndMethod

	#tag Method, Flags = &h0
		Function CountOfValue(theValue as CFType) As Integer
		  #if TargetMacOS
		    declare function CFSetGetCountOfValue lib CarbonLib (theSet as Ptr, value as Ptr) as Integer
		    
		    if not ( self = nil ) then
		      return CFSetGetCountOfValue(me.Reference, theValue.Reference)
		    end if
		  #endif
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function HasValue(value as CFType) As Boolean
		  #if TargetMacOS
		    declare function CFSetContainsValue lib CarbonLib (theSet as Ptr, value as Ptr) as Boolean
		    
		    if not ( self = nil ) and not (value is nil) then
		      return CFSetContainsValue(me.Reference, value.Reference)
		    end if
		  #endif
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function Lookup(value as CFType, fallbackValue as CFType) As CFType
		  #if TargetMacOS
		    declare function CFSetGetValueIfPresent lib CarbonLib (theSet as Ptr, candidate as Ptr, ByRef value as Ptr) as Boolean
		    
		    if not ( self = nil ) and not (value is nil) then
		      dim theValue as Ptr
		      if CFSetGetValueIfPresent(me.Reference, value.Reference, theValue) then
		        return CFType.NewObject(theValue, false, kCFPropertyListImmutable)
		      end if
		    end if
		  #endif
		  
		  return fallbackValue
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function Value(value as CFType) As CFType
		  // Note: this function may actually return nil - that's if the value does not exist in the set
		  
		  #if TargetMacOS
		    declare function CFSetGetValueIfPresent lib CarbonLib (theSet as Ptr, candidate as Ptr, ByRef value as Ptr) as Boolean
		    
		    if not ( self = nil ) and not (value is nil) then
		      dim theValue as Ptr
		      if CFSetGetValueIfPresent(me.Reference, value.Reference, theValue) then
		        return CFType.NewObject(theValue, false, kCFPropertyListImmutable)
		      end if
		    end if
		  #endif
		End Function
	#tag EndMethod

	#tag Method, Flags = &h0
		Function Values() As CFType()
		  dim theList() as CFType
		  #if TargetMacOS
		    if not ( self = nil ) then
		      dim setCount as Integer = me.Count
		      if setCount > 0 then
		        declare sub CFSetGetValues lib CarbonLib (theSet as Ptr, values as Ptr)
		        
		        const sizeOfCFTypeRef = 4
		        dim valueList as new MemoryBlock(sizeOfCFTypeRef*setCount)
		        CFSetGetValues me.Reference, valueList
		        
		        dim offset as Integer = 0
		        for i as Integer = 1 to setCount
		          theList.Append CFType.NewObject(valueList.Ptr(offset), false, kCFPropertyListImmutable)
		          offset = offset + sizeOfCFTypeRef
		        next
		      end if
		    end if
		  #endif
		  // we always returns a non-nil list, even if it's empty!
		  return theList
		End Function
	#tag EndMethod


	#tag ComputedProperty, Flags = &h0
		#tag Getter
			Get
			  #if TargetMacOS
			    declare function CFSetGetCount lib CarbonLib (theSet as Ptr) as Integer
			    
			    if not ( self = nil ) then
			      return CFSetGetCount(me.Reference)
			    end if
			  #endif
			End Get
		#tag EndGetter
		Count As Integer
	#tag EndComputedProperty


	#tag ViewBehavior
		#tag ViewProperty
			Name="Count"
			Group="Behavior"
			Type="Integer"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Description"
			Group="Behavior"
			Type="String"
			EditorType="MultiLineEditor"
			InheritedFrom="CFType"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Index"
			Visible=true
			Group="ID"
			InitialValue="-2147483648"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Left"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Name"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Super"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Top"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
	#tag EndViewBehavior
End Class
#tag EndClass
